/**
 * @date 2005-12-20 13:24:56
 *
 */
package org.nanhill.xsheet.input.xhtml;

import static org.nanhill.commons.html.CssTag.CSS_BGCOLOR;
import static org.nanhill.commons.html.CssTag.CSS_TEXT_ALIGN;
import static org.nanhill.commons.html.XhtmlConstants.BODY;
import static org.nanhill.commons.html.XhtmlConstants.CLASS;
import static org.nanhill.commons.html.XhtmlConstants.COLSPAN;
import static org.nanhill.commons.html.XhtmlConstants.HEAD;
import static org.nanhill.commons.html.XhtmlConstants.HTML;
import static org.nanhill.commons.html.XhtmlConstants.ID;
import static org.nanhill.commons.html.XhtmlConstants.ROWSPAN;
import static org.nanhill.commons.html.XhtmlConstants.STYLE;
import static org.nanhill.commons.html.XhtmlConstants.TABLE;
import static org.nanhill.commons.html.XhtmlConstants.TD;
import static org.nanhill.commons.html.XhtmlConstants.TR;

import java.util.Iterator;

import org.dom4j.Element;
import org.dom4j.Node;
import org.nanhill.commons.model.table.Cell;
import org.nanhill.commons.model.table.Row;
import org.nanhill.commons.model.table.Table;
import org.nanhill.xsheet.XSheetParseException;
import org.nanhill.xsheet.model.XSheetModel;
import org.nanhill.xsheet.model.XSheetStyle;

/**
 * not thread safe
 * 
 * @author alin
 * 
 */
public class DefaultXhtmlInputBuilder extends XhtmlInputBuilder {
	private Element root;

	protected void initModel() throws XSheetParseException {
		this.model = new XSheetModel();
		this.root = document.getRootElement();
		if (!root.getName().equals(HTML)) {
			throw new XSheetParseException("root element must be <html>.");
		}
	}

	@Override
	protected void buildStyle() throws XSheetParseException {
		Element ele = (Element) root.selectSingleNode(HEAD);
		if (null == ele) {
			throw new XSheetParseException(
					"root node must has a element named <head>.");
		}
		for (int i = 0, size = ele.nodeCount(); i < size; i++) {
			Node style = ele.node(i);
			String name = style.getName();
			if (null != name && name.equals(STYLE)) {
				this.buildStyle((Element) style);
			}
		}
	}

	@Override
	protected void buildTables() throws XSheetParseException {
		Element ele = (Element) root.selectSingleNode(BODY);
		if (null == ele) {
			throw new XSheetParseException(
					"root node must has a child element named <body>.");
		}
		for (int i = 0, size = ele.nodeCount(); i < size; i++) {
			Node table = ele.node(i);
			String name = table.getName();
			if (null != name && name.equals(TABLE)) {
				this.buildTable((Element) table);
			}
		}
	}

	protected void buildStyle(Element ele) throws XSheetParseException {
		XSheetStyle style = new XSheetStyle();
		int id = Integer.parseInt(ele.attributeValue(ID));
		style.setId(id);
		String attr = ele.attributeValue(CSS_BGCOLOR);
		if (null != attr) {
			style.setBgColor(attr);
		}
		attr = ele.attributeValue(CSS_TEXT_ALIGN);
		if (null != attr)
			style.setAlignment(attr);
		this.model.addStyle(style);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.nanhill.analyzer.sheet.parser.input.html.HtmlInputBuilder#buildModel()
	 */
	protected void buildTable(Element ele) throws XSheetParseException {
		String tableName = ele.attributeValue(ID);
		if (null == tableName) {
			tableName = "BUILD BY XSHEET";
		}
		Table table = this.model.createTable(tableName);
		for (Iterator itt = ele.elementIterator(); itt.hasNext();) {
			Node element = (Node) itt.next();
			String name = element.getName();
			if (null != name && name.equals(TR)) {
				this.buildRow((Element) element, table);
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.nanhill.protocol.xsheet.input.html.HtmlInputBuilder#readTr(org.dom4j.Element,
	 *      org.nanhill.base.model.table.Table)
	 */
	protected void buildRow(Element ele, Table table)
			throws XSheetParseException {
		Row row = table.createRow();
		for (Iterator itt = ele.elementIterator(); itt.hasNext();) {
			Node element = (Node) itt.next();
			String name = element.getName();
			if (null != name && name.equals(TD)) {
				this.buildCell((Element) element, row);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.nanhill.protocol.xsheet.input.html.HtmlInputBuilder#readTd(org.dom4j.Element,
	 *      org.nanhill.base.model.table.Row)
	 */
	protected void buildCell(Element ele, Row row) throws XSheetParseException {
		Cell cell = row.createCell(ele.getText());
		int attrValue;
		String attr = ele.attributeValue(ROWSPAN);
		attrValue = null == attr ? 1 : Integer.parseInt(attr);
		cell.setRowspan(attrValue);
		attr = ele.attributeValue(COLSPAN);
		attrValue = null == attr ? 1 : Integer.parseInt(attr);
		cell.setColspan(attrValue);
		attr = ele.attributeValue(CLASS);
		if (null != attr) {
			attrValue = Integer.parseInt(attr);
			cell.setStyleId(attrValue);
		}
	}



}
